// 玩家实体模型

/**
 * 玩家技能等级枚举
 */
export enum SkillLevel {
  BEGINNER = 'beginner',
  INTERMEDIATE = 'intermediate',
  ADVANCED = 'advanced',
  EXPERT = 'expert'
}

/**
 * 玩家成就接口
 */
export interface Achievement {
  id: number;
  name: string;
  description: string;
  unlockedAt: string;
  icon?: string;
  points: number;
}

/**
 * 玩家统计数据接口
 */
export interface PlayerStats {
  casesSolved: number;
  casesFailed: number;
  accuracyRate: number;
  totalPlayTime: number; // 单位：分钟
  averageTimePerCase: number; // 单位：分钟
}

/**
 * 玩家技能接口
 */
export interface PlayerSkill {
  type: 'observation' | 'deduction' | 'analysis' | 'intuition';
  level: SkillLevel;
  experience: number;
  maxExperience: number;
}

/**
 * 玩家实体类
 */
export class Player {
  id: number;
  name: string;
  avatar?: string;
  level: number;
  experience: number;
  rank: string;
  joinDate: string;
  lastLoginDate: string;
  stats: PlayerStats;
  skills: PlayerSkill[];
  achievements: Achievement[];
  currentCaseId?: number;

  constructor(
    id: number,
    name: string,
    avatar?: string,
    level: number = 1,
    experience: number = 0,
    rank: string = '实习侦探',
    joinDate: string = new Date().toISOString(),
    lastLoginDate: string = new Date().toISOString(),
    stats?: Partial<PlayerStats>,
    skills?: PlayerSkill[],
    achievements: Achievement[] = []
  ) {
    this.id = id;
    this.name = name;
    this.avatar = avatar;
    this.level = level;
    this.experience = experience;
    this.rank = rank;
    this.joinDate = joinDate;
    this.lastLoginDate = lastLoginDate;
    
    // 初始化玩家统计数据
    this.stats = {
      casesSolved: stats?.casesSolved || 0,
      casesFailed: stats?.casesFailed || 0,
      accuracyRate: stats?.accuracyRate || 0,
      totalPlayTime: stats?.totalPlayTime || 0,
      averageTimePerCase: stats?.averageTimePerCase || 0
    };
    
    // 初始化玩家技能
    this.skills = skills || [
      { type: 'observation', level: SkillLevel.BEGINNER, experience: 0, maxExperience: 100 },
      { type: 'deduction', level: SkillLevel.BEGINNER, experience: 0, maxExperience: 100 },
      { type: 'analysis', level: SkillLevel.BEGINNER, experience: 0, maxExperience: 100 },
      { type: 'intuition', level: SkillLevel.BEGINNER, experience: 0, maxExperience: 100 }
    ];
    
    this.achievements = achievements;
  }

  /**
   * 获取玩家当前等级所需的总经验值
   */
  getLevelExperience(): number {
    // 简单的等级经验计算公式：level * 1000
    return this.level * 1000;
  }

  /**
   * 获取下一级所需的经验值
   */
  getNextLevelExperience(): number {
    return (this.level + 1) * 1000;
  }

  /**
   * 添加经验值
   * @param exp 要添加的经验值
   * @returns 是否升级
   */
  addExperience(exp: number): boolean {
    this.experience += exp;
    const nextLevelExp = this.getNextLevelExperience();
    
    if (this.experience >= nextLevelExp) {
      this.levelUp();
      return true;
    }
    return false;
  }

  /**
   * 升级玩家
   */
  private levelUp(): void {
    this.level++;
    // 更新玩家等级对应的称号
    this.updateRank();
    console.log(`${this.name} 升级了！当前等级：${this.level}，称号：${this.rank}`);
  }

  /**
   * 根据等级更新玩家称号
   */
  private updateRank(): void {
    if (this.level >= 20) {
      this.rank = '传奇侦探';
    } else if (this.level >= 15) {
      this.rank = '资深侦探';
    } else if (this.level >= 10) {
      this.rank = '高级侦探';
    } else if (this.level >= 5) {
      this.rank = '中级侦探';
    } else {
      this.rank = '初级侦探';
    }
  }

  /**
   * 增加技能经验
   * @param skillType 技能类型
   * @param exp 要添加的经验值
   * @returns 是否升级技能
   */
  addSkillExperience(skillType: PlayerSkill['type'], exp: number): boolean {
    const skill = this.skills.find(s => s.type === skillType);
    if (!skill) return false;
    
    skill.experience += exp;
    
    // 检查技能是否可以升级
    if (skill.experience >= skill.maxExperience) {
      this.levelUpSkill(skill);
      return true;
    }
    return false;
  }

  /**
   * 升级技能
   */
  private levelUpSkill(skill: PlayerSkill): void {
    const levelValues = Object.values(SkillLevel);
    const currentIndex = levelValues.indexOf(skill.level);
    
    if (currentIndex < levelValues.length - 1) {
      skill.level = levelValues[currentIndex + 1] as SkillLevel;
      skill.experience = 0;
      skill.maxExperience *= 1.5; // 每次升级提高所需经验
      console.log(`${this.name} 的 ${this.getSkillName(skill.type)} 技能升级到 ${this.getSkillLevelName(skill.level)}！`);
    }
  }

  /**
   * 获取技能名称
   */
  private getSkillName(type: PlayerSkill['type']): string {
    const skillNames = {
      observation: '观察力',
      deduction: '推理能力',
      analysis: '分析能力',
      intuition: '直觉'
    };
    return skillNames[type];
  }

  /**
   * 获取技能等级名称
   */
  private getSkillLevelName(level: SkillLevel): string {
    const levelNames = {
      [SkillLevel.BEGINNER]: '入门',
      [SkillLevel.INTERMEDIATE]: '熟练',
      [SkillLevel.ADVANCED]: '精通',
      [SkillLevel.EXPERT]: '专家'
    };
    return levelNames[level];
  }

  /**
   * 解锁成就
   * @param achievement 要解锁的成就
   */
  unlockAchievement(achievement: Omit<Achievement, 'unlockedAt'>): boolean {
    // 检查成就是否已解锁
    if (this.achievements.some(a => a.id === achievement.id)) {
      return false;
    }
    
    const unlockedAchievement: Achievement = {
      ...achievement,
      unlockedAt: new Date().toISOString()
    };
    
    this.achievements.push(unlockedAchievement);
    // 成就解锁可以获得额外经验
    this.addExperience(achievement.points);
    console.log(`${this.name} 解锁了成就：${achievement.name}！`);
    return true;
  }

  /**
   * 更新玩家统计数据
   * @param caseResult 案件结果（成功或失败）
   * @param playTime 本次案件用时（分钟）
   */
  updateCaseStats(caseResult: 'success' | 'failure', playTime: number): void {
    if (caseResult === 'success') {
      this.stats.casesSolved++;
    } else {
      this.stats.casesFailed++;
    }
    
    this.stats.totalPlayTime += playTime;
    const totalCases = this.stats.casesSolved + this.stats.casesFailed;
    this.stats.averageTimePerCase = this.stats.totalPlayTime / totalCases;
    this.stats.accuracyRate = this.stats.casesSolved / totalCases * 100;
    
    // 更新最后登录时间
    this.lastLoginDate = new Date().toISOString();
  }

  /**
   * 开始新案件
   * @param caseId 案件ID
   */
  startCase(caseId: number): void {
    this.currentCaseId = caseId;
  }

  /**
   * 完成当前案件
   */
  completeCase(): void {
    this.currentCaseId = undefined;
  }

  /**
   * 获取玩家信息摘要
   */
  getSummary(): {
    id: number;
    name: string;
    level: number;
    rank: string;
    casesSolved: number;
    accuracyRate: number;
  } {
    return {
      id: this.id,
      name: this.name,
      level: this.level,
      rank: this.rank,
      casesSolved: this.stats.casesSolved,
      accuracyRate: Math.round(this.stats.accuracyRate * 10) / 10 // 保留一位小数
    };
  }
}